package com.tqyan.service.chat.impl.novel;

import com.tqyan.dal.mapper.NovelMapper;
import com.tqyan.dal.mapper.NovelSceneMapper;
import com.tqyan.model.controller.request.OpenAIChatMessageRequest;
import com.tqyan.model.controller.request.OpenAIChatRequest;
import com.tqyan.model.dto.*;
import com.tqyan.model.enums.ChatContentTypeEnum;
import com.tqyan.model.enums.ChatCreativeAbilityEnum;
import com.tqyan.model.enums.GPTModelEnum;
import com.tqyan.model.enums.GPTRoleEnum;
import com.tqyan.service.chat.AbstractChatPointService;
import com.tqyan.service.chat.ChatPointContent;
import com.tqyan.util.SnowflakeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * @description 小说类型
 * <p> <功能详细描述> </p>
 *
 * @author 陈晨
 * @date 2023/6/13 17:51
 */
@Service
@Slf4j
public class NovelNextOptionChatPointService extends AbstractChatPointService {

    @Autowired
    private NovelMapper novelMapper;
    @Autowired
    private NovelSceneMapper novelSceneMapper;
    @Autowired
    private NovelViewChatPointService novelViewChatPointService;

    @Override
    public String getPoint() {
        return ChatPointContent.NOVEL_NEXT_OPTION;
    }

    @Override
    public ChatContentDTO chatPoint(UserDTO user, UserSettingDTO userSetting, ChatDTO chat, String content) {
        // 1, 获取小说标题
        // 2, 格式错误, 转默认对话
        content = content.replaceAll("：", ":");
        if (content.split(":").length < 2) {
            return null;
        }
        String title = content.split(":")[1].trim();

//        // 获取最后一个回答
//        List<ChatContentDTO> lastContentList = chatContentMapper.queryByChatByRole(
//                chat.getId(), null, 0, 1);
//        if (CollectionUtils.isEmpty(lastContentList)) {
//            return null;
//        }
//        ChatContentDTO answer = lastContentList.get(0);

        // 3.1, 查询小说
        NovelDTO novel = novelMapper.queryByTitle(user.getId(), title);
        if (null == novel) {
            // 3.1, 小说不存在: 转查询
            String viewContent = ChatPointContent.NOVEL_VIEW + ":" + title;
            return novelViewChatPointService.chat(user, userSetting, chat, viewContent);
        }
        NovelSceneDTO novelSceneLast = novelSceneMapper.queryLastByNovel(user.getId(), novel.getId());

        // 4, 写下一幕
        // 记录对话
        ChatContentDTO question = super.createQuestion(user, userSetting, chat, content, null, null);
        ChatContentDTO answer = super.createAnswer(userSetting, question, null);

        // 设置问题
//        ChatContentDTO question = new ChatContentDTO();
//        question.setId(SnowflakeUtils.nextId());
//        question.setUserId(user.getId());
//        question.setChatId(chat.getId());
//        question.setModel(userSetting.getModel());
//        question.setTemperature(ChatCreativeAbilityEnum.get(userSetting.getCreativeAbility()).getTemperature());
//        question.setRole(GPTRoleEnum.USER.getValue());
//        question.setType(ChatContentTypeEnum.TEXT.getValue());
//        question.setGptModel(GPTModelEnum.GPT_3_5.getValue());
        question.setContent(novelSceneLast.getContent() + "_" + novel.getTitle() + "_" + novel.getType());
        // 设置回答内容
        answer.setContent(novelSceneLast.getContent() + ChatPointContent.NOVEL_SPLIT);
        // 请求问题, 答案流响应
        super.chatExecute(user, userSetting, chat, question, answer);
        return answer;
    }

    @Override
    protected void requestChatComplete(UserDTO user, UserSettingDTO userSetting, ChatDTO chat
            , ChatContentDTO question, ChatContentDTO completeAnswer) {
        // 拆分场景、下一幕
        String[] splits = completeAnswer.getContent().split(ChatPointContent.NOVEL_SPLIT);
        String scene = splits[0];
        String nextOption = splits[1];
        // 处理下一幕
        if (nextOption.contains("\n\n")) {
            splits = nextOption.split("\n\n");
            if (splits.length > 5) {
                nextOption = StringUtils.join(
                        splits[1] + "\n"
                        , splits[2] + "\n"
                        , splits[3] + "\n"
                        , splits[4] + "\n"
                        , splits[5]);
            } else if (splits.length < 5) {
                nextOption = splits[1];
            } else {
                nextOption = StringUtils.join(
                        splits[0] + "\n"
                        , splits[1] + "\n"
                        , splits[2] + "\n"
                        , splits[3] + "\n"
                        , splits[4]);
            }
        }

        // 更新场景下一幕
        String title = question.getContent().split("_")[1].trim();
        NovelDTO novel = novelMapper.queryByTitle(user.getId(), title);
        NovelSceneDTO novelSceneLast = novelSceneMapper.queryLastByNovel(user.getId(), novel.getId());
        NovelSceneDTO novelScene = new NovelSceneDTO();
        novelScene.setId(novelSceneLast.getId());
        novelScene.setUserId(user.getId());
        novelScene.setNextOption(nextOption);
        boolean result = novelSceneMapper.update(novelScene) > 0;
        log.info("[{}] userId={}, chatId={}, answerId={}, novelScene={}, 更新场景下一幕: {}"
                , this.getPoint(), user.getId(), completeAnswer.getChatId(), completeAnswer.getId()
                , novelScene.getId(), result);

        // 更新回答内容
        String[] nextOptions = nextOption.split("\n");
        String[] btns = new String[nextOptions.length];
        for (int i = 0; i < nextOptions.length; i++) {
            if (StringUtils.isBlank(nextOptions[i])) {
                continue;
            }
            btns[i] = String.format(
                    ChatPointContent.BTN_AUTO_TRUE
                    , ChatPointContent.NOVEL_NEXT_SCENE + ":" + novel.getTitle() + "_" + nextOptions[i]
                    , nextOptions[i]);
        }
        String answerContent = ChatPointContent.generateButtonResult(scene + "\n", btns);
        ChatContentDTO updateChatContent = new ChatContentDTO();
        updateChatContent.setId(completeAnswer.getId());
        updateChatContent.setChatId(completeAnswer.getChatId());
        updateChatContent.setContent(answerContent);
        result = chatContentMapper.update(updateChatContent) > 0;
        log.info("[{}] userId={}, chatId={}, answerId={}, novelScene={}, 更新回答内容: {}"
                , this.getPoint(), user.getId(), completeAnswer.getChatId(), completeAnswer.getId()
                , novelScene.getId(), result);
    }

    @Override
    protected OpenAIChatRequest generateChatRequest(UserSettingDTO userSetting, ChatContentDTO question) {
        OpenAIChatRequest chatRequest = new OpenAIChatRequest();
        chatRequest.setModel(question.getGptModel());
        chatRequest.setTemperature(question.getTemperature() / 10D);
        OpenAIChatMessageRequest message = chatRequest.addMessage(question.getRole(), question.getContent());
        // 获取小说标题、类型
        String scene = question.getContent().split("_")[0].trim();
        String title = question.getContent().split("_")[1].trim();
        String type = question.getContent().split("_")[2].trim();
        // 设置对话内容
        String content = "“%s”\n\n"
                + "这是一部关于“%s”的“%s”小说，根据以上情节，给我5个可能得剧情发展方向。";
        message.setContent(String.format(content, scene, title, type));
        log.info("[{}] userId={}, chatId={}, chatRequest={}, 构建聊天请求"
                , this.getPoint(), question.getUserId(), question.getChatId(), chatRequest);
        return chatRequest;
    }

    public static void main(String[] args) {
        String nextOption =
                "ddadasdasdasdadnanaldjalj\n\n" +
                "1. 李满和他的小组成员遇到了一起危机，需要联合其他组织或修仙者共同抵御外敌的威胁。\n" +
                "2. 李满和他的小组成员在探索修仙界中，发现了一个古老的秘密，必须联手打败敌人并保护这个秘密。\n" +
                "3. 李满和他的小组成员被卷入了一个史诗级的战争中，为了保护自己和联盟的利益，他们必须全力以赴。\n" +
                "4. 李满和他的小组成员发现了一些不为人知的黑暗势力，必须全力查明事实真相并打败他们。\n" +
                "5. 李满和他的小组成员面对内部分歧，需要进行艰苦的斗争和劝说，最终达成共识并继续保卫联盟的利益。\n" +
                "6. 123123123123123。\n";
        // 处理下一幕
        if (nextOption.contains("\n\n")) {
            String[] splits = nextOption.split("\n\n");
            if (splits.length > 5) {
                nextOption = StringUtils.join(
                        splits[1] + "\n"
                        , splits[2] + "\n"
                        , splits[3] + "\n"
                        , splits[4] + "\n"
                        , splits[5]);
            } else if (splits.length < 5) {
                nextOption = splits[1];
            } else {
                nextOption = StringUtils.join(
                        splits[0] + "\n"
                        , splits[1] + "\n"
                        , splits[2] + "\n"
                        , splits[3] + "\n"
                        , splits[4]);
            }
        }
        System.out.println(nextOption);
    }

}


